﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Diagnostics;

namespace LowLevelGraphics.ColorSpaces
{
    /// <summary>
    /// CMYK Channel
    /// </summary>
    public enum CMYKChannel
    {
        /// <summary>
        /// 
        /// </summary>
        C = 0,
        /// <summary>
        /// 
        /// </summary>
        M = 1,
        /// <summary>
        /// 
        /// </summary>
        Y = 2,
        /// <summary>
        /// 
        /// </summary>
        K = 3
    }

    /// <summary>
    /// This simple conversion uses NO icc color management features
    /// </summary>
    [DebuggerDisplay(" C: {m_C}, M: {m_M} Y: {m_Y}, K: {m_K}")]
    public class CMYK : AbstractColorSpace
    {
        protected int m_C = -1;
        protected int m_M = -1;
        protected int m_Y = -1;
        protected int m_K = -1;

        /// <summary>
        /// Initializes a new instance of the <see cref="CMYK"/> class.
        /// </summary>
        /// <param name="_color">The _color.</param>
        public CMYK(Color _color)
            : base(_color)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CMYK"/> class.
        /// </summary>
        /// <param name="_C">The _ C.</param>
        /// <param name="_M">The _ M.</param>
        /// <param name="_Y">The _ Y.</param>
        /// <param name="_K">The _ K.</param>
        public CMYK(int _C, int _M, int _Y, int _K)
        {
            m_C = _C;
            m_M = _M;
            m_Y = _Y;
            m_K = _K;
        }

        /// <summary>
        /// Used to calculate new channel values from rgb
        /// This is a simple formula WITHOUT ICC (Color management)
        /// </summary>
        protected override void CalcValues()
        {
            int nR = m_Color.R;
            int nG = m_Color.G;
            int nB = m_Color.B;

            m_K = Math.Min(Math.Min(255 - nR, 255 - nG), 255 - nB);
            m_C = (255 - nR - m_K) / (255 - m_K);
            m_M = (255 - nG - m_K) / (255 - m_K);
            m_Y = (255 - nB - m_K) / (255 - m_K); 
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_color"></param>
        /// <returns></returns>
        public static explicit operator CMYK(Color _color)
        {
            return new CMYK(_color);
        }

        /// <summary>
        /// Override this to implement retransformation of concrete color space
        /// back to rgb
        /// </summary>
        /// <returns></returns>
        public override Color ToColor()
        {
            return Color.FromArgb(m_C - m_K, m_M - m_K, m_Y - m_K);
        }

        /// <summary>
        /// Gets the values.
        /// </summary>
        /// <returns></returns>
        public override object[] GetValues()
        {
            return new object[] { new object[] { m_C, m_M, m_Y, m_K } };
        }

        /// <summary>
        /// Sets the values.
        /// </summary>
        /// <param name="_aObject">The _a object.</param>
        public override void SetValues(object[] _aObject)
        {
            m_C = (int)_aObject[0];
            m_M = (int)_aObject[1];
            m_Y = (int)_aObject[2];
            m_K = (int)_aObject[3];
        }
    }
}
